<template>
  <el-form
    ref="form"
    :model="form"
    label-width="80px"
    size="small"
    :rules="rules"
  >
    <div
      class="form-module"
      v-for="(item, index) in itemsComputed"
      :key="index"
    >
      <div class="form-module-title">{{ item.title }}</div>
      <div class="form-module-content">
        <el-row :gutter="20" v-if="item.fields && item.fields.length > 0">
          <el-col
            v-for="(item2, index1) in item.fields"
            :span="item2.span || 4"
            :key="index1"
          >
            <el-form-item :label="item2.text" :prop="item2.field">
              <!-- 输入框 -->
              <el-input
                v-if="item2.type == 'input'"
                v-model="form[item2.field]"
                @change="formChangeHandler(item2.field, $event)"
              ></el-input>
              <!-- 下拉框 -->
              <template v-if="item2.type == 'dataItem'">
                <el-select
                  v-model="form[item2.field]"
                  filterable
                  :placeholder="item2.placeholder"
                  size="small"
                  clearable
                  :multiple="item2.multiple"
                  @change="formChangeHandler(item2.field, $event)"
                >
                  <el-option
                    v-for="item3 in item2.options"
                    :key="item3.value"
                    :label="item3.label"
                    :value="item3.value"
                  >
                  </el-option>
                </el-select>
              </template>
              <!-- 日期 -->
              <y-date
                v-if="item2.type == 'date'"
                v-model="form[item2.field]"
                @change="formChangeHandler(item2.field, $event)"
              ></y-date>
              <!-- 联级选择、树形选择 -->
              <el-cascader
                v-if="item2.type == 'cascader'"
                expand-trigger="hover"
                :options="cascaderOptions[item2.field]"
                v-model="form[item2.field]"
                change-on-select
                @change="formChangeHandler(item2.field, $event)"
              >
              </el-cascader>
              <!-- 多选 -->
              <el-checkbox
                v-if="item2.type == 'checkbox'"
                v-model="form[item2.field]"
                @change="formChangeHandler(item2.field, $event)"
                >备选项</el-checkbox
              >
              <!-- 多选组 -->
              <template v-if="item2.type == 'checkbox-group' && item2.items">
                <el-checkbox
                  v-for="checkItem in item2.items"
                  :key="checkItem.field"
                  v-model="form[checkItem.field]"
                  :disabled="checkItem.disabled"
                  @change="formChangeHandler(item2.field, $event)"
                  >{{ checkItem.text }}</el-checkbox
                >
              </template>
              <!-- 图片 -->
              <template v-if="item2.type == 'picture'">
                <el-upload
                  class="avatar-uploader"
                  :action="
                    $store.state.base.baseURL +
                    $store.state.base.uploadURL +
                    'images'
                  "
                  :show-file-list="false"
                  :on-success="pictureSuccess"
                  :on-remove="pictureRemove"
                  ref="$pictureUpload"
                  :field="item2.field"
                  >
                  <img v-if="form[item2.field]" :src="$store.state.base.baseURL + form[item2.field]"  class="avatar" style="width: 178px;height: 178px;display: block;">
                  <i v-else class="el-icon-plus avatar-uploader-icon" style="font-size: 28px;color: #8c939d;width: 178px;height: 178px;line-height: 178px;text-align: center;"></i>
                </el-upload>
              </template>
              <!-- 图片组 -->
              <template v-if="item2.type == 'picture-group'">
                <el-upload
                  :action="
                    $store.state.base.baseURL +
                    $store.state.base.uploadURL +
                    'images'
                  "
                  :field="item2.field"
                  list-type="picture-card"
                  accept="image/*"
                  :limit="10"
                  multiple
                  @change="formChangeHandler(item2.field, $event)"
                  :file-list="form[item2.field]"
                  :on-preview="pictureGroupPreview"
                  :on-remove="pictureGroupRemove"
                  :on-success="pictureGroupSuccess"
                  :on-error="pictureGroupError"
                  :on-progress="pictureGroupProgress"
                  :on-change="pictureGroupChange"
                  ref="$pictureGroupUpload"
                >
                  <i class="el-icon-plus"></i>
                </el-upload>
              </template>

              <!-- 富文本编辑器 -->
              <template v-if="item2.type == 'rich-editor'">
                <div :id="`rich-editor-${item2.field}`"></div>
              </template>

              <!-- 插槽 -->
              <template v-if="item2.type == 'slot'">
                <slot :name="item2.field"></slot>
              </template>
            </el-form-item>
          </el-col>
        </el-row>
        <y-table
          v-if="item.columns && item.columns.length > 0"
          :ref="'$' + item.field"
          v-bind="item"
        ></y-table>
      </div>
    </div>

    <!-- 图片预览 -->
    <el-dialog :visible.sync="picturePreviewDialogVisible" >
      <el-carousel ref="$pictureGroupCarousel" indicator-position="outside" height="100vh" :autoplay="false" :initial-index="picturePreviewIndex">
        <el-carousel-item v-for="item in picturePreviewList" :key="item.url" >
          <h3>{{item.name}}</h3>
          <img :src="`${$store.state.base.baseURL}${item.path}/${item.storageName}`" style="width:100%"/>
        </el-carousel-item>
      </el-carousel>
    </el-dialog>
  </el-form>
</template>

<script>
export default {
  name: "y-form",
  props: {
    items: Array,
    models: Array,
  },
  data() {
    return {
      form: {},
      rules: {},
      tables: [],
      cascaderOptions: {},
      dataItemOptions: {},
      initialized: false,
      ready: false,
      picturePreviewDialogVisible: false,
      picturePreviewList:[],
      picturePreviewIndex:0,
      richTextEditorList:[],
      editor:null
    };
  },
  computed: {
    itemsComputed() {
      var items = this.items;
      items.forEach((item) => {
        if (item.fields) {
          item.fields.forEach((f) => {
            // 图片组
            if(['picture-group'].includes(f.type)){
              if(this.form[f.field]){
                this.form[f.field].forEach(i=>{
                  if(i.url && !i.url.includes(this.$store.state.base.baseURL)){
                    i.url = `${this.$store.state.base.baseURL}${i.path}/${i.storageName}`
                  }
                })
              }else{
                this.form[f.field] = []
              }
            }
          });
        }
        if (item.columns && item.columns.length > 0) {
          item.data = this.form[item.field] || [];
          if (!this.tables.includes(item.field)) {
            this.tables.push(item.field);
          }
        }
      });
      return items;
    },
  },
  async created() {
    var _this = this;
    var form = {};
    // model 处理
    if (_this.models) {
      _this.models.forEach((model) => {
        _this.$y._.assign(form, model);
      });
    }
    for (let i = 0; i < _this.items.length; i++) {
      var item = _this.items[i];
      if (item.fields) {
        for (let j = 0; j < item.fields.length; j++) {
          let f = item.fields[j];
          form[f.field] = _this.form[f.field] || null;
          _this.ganerateRules(f);
          // 数据项
          if (f.type == "dataItem") {
            f.options = [];
            if (f.code) {
              var { data } = await $y.api.system.dataItem.getItems(f.code);
              data.forEach((d) => (d.value = parseInt(d.value || 0)));
              f.options = data;
              _this.dataItemOptions[f.code] = data;
            }
            if (f.action) {
              var { data } = await $y.api.system.dataItem.getAction(f.action);
              f.options = data;
              _this.dataItemOptions[f.action] = data;
            }
          }

          // 层次数据、树形...
          if (["tree", "cascader"].includes(f.type)) {
            _this.cascaderOptions[f.field] = [];
            var { data } = await $y.api.system.dataItem.getCascades(f.code);
            _this.cascaderOptions[f.field] = data;
          }

          if(['rich-editor'].includes(f.type)){
            _this.editor = _this.editor || require('wangeditor')

            var formEditor = new _this.editor(`#rich-editor-${f.field}`)
            formEditor.create()

            _this.richTextEditorList.push({
              editor:formEditor,
              field:f.field
            })
          }
        }
      }

      if (item.columns && item.columns.length > 0) {
        item["data"] = _this.form[item.field] || [];
        form[item.field] = _this.form[item.field] || [];
        if (!_this.tables.includes(item.field)) {
          _this.tables.push(item.field);
        }
      }
    }
    _this.form = form;
    _this.initialized = true;
    _this.$emit("ready");
  },
  mounted() {
    document.querySelectorAll(".el-select.el-select--small").forEach((el) => {
      el.style.width = "100%";
    });
    var el = document.querySelector(".avatar-uploader .el-upload");
    if(el){
        $y._.assign(el.style,{
        'border':'1px dashed #d9d9d9',
        'border-radius':'6px',
        'cursor':'pointer',
        'position':'relative',
        'overflow':'hidden'
      })
    }
    
    
  },
  methods: {
    ganerateRules(item2) {
      var { type, required, text, field } = item2;
      this.rules[field] = [];
      if (required) {
        this.rules[field].push({
          required: true,
          message: `${text}不能为空`,
          trigger: "blur",
        });
      }
      if (type == "email") {
        item2.type = "input";
        this.rules[field].push({
          type: "email",
          message: "请输入正确的邮箱地址",
          trigger: "blur",
        });
      }
      if (type == "phone") {
        item2.type = "input";
        this.rules[field].push({
          type: "phone",
          message: "请输入正确的手机号码",
          trigger: "blur",
        });
      }

      if (type == "address") {
        item2.type = "input";
      }

      if (["decamal", "int", "long"].includes(type)) {
        item2.type = "input";
      }

      if (type == "bank") {
        item2.type = "input";
      }
    },
    getFormData() {
      var _this = this;
      if (_this.tables.length > 0) {
        _this.tables.forEach((t) => {
          let refKey = "$" + t;
          var { visibleData } = _this.$refs[refKey][0].api.getTableData();
          _this.form[t] = visibleData;
        });
      }
      if (_this.items.length > 0) {
        _this.items.forEach((item) => {
          if (item.fields) {
            item.fields.forEach((f) => {
              // 层次数据、树形...
              if (
                ["tree", "cascader"].includes(f.type) &&
                Array.isArray(_this.form[f.field])
              ) {
                _this.form[f.field] =
                  _this.form[f.field][_this.form[f.field].length - 1];
              }

              // 富文本编辑
              if(_this.richTextEditorList.length > 0){
                _this.richTextEditorList.forEach(e=>{
                  _this.form[e.field] = e.editor.txt.html()
                })
              }

            });

          }
        });
      }
      return _this.form;
    },
    setData(data) {
      var _this = this;
      if (_this.initialized) {
        for (let f in data) {
          _this.form[f] = data[f];
        }

        if(_this.richTextEditorList.length > 0){
          _this.richTextEditorList.forEach(e=>{
            e.editor.txt.html(_this.form[e.field])
          })
        }

        _this.ready = true;
      } else {
        setTimeout(() => _this.setData(data), 100);
      }
    },
    /**
     * 编辑器初始化
     */
    initEditor(id,field){
      // if(this.$el.querySelector())
    },
    /**
     * 表单修改事件总线
     */
    formChangeHandler(field, event) {
      this.$emit("change", { field, event });
    },
    /**
     * 单张图片上传成功
     */
    pictureSuccess(response,file){
      var field = this.$refs.$pictureUpload[0].$el.getAttribute('field');
      this.form[field] = `${response.data.path}/${response.data.storageName}`
      
    },
    /**
     * 单张图片删除
     */
    pictureRemove(file){
      var field = this.$refs.$pictureUpload[0].$el.getAttribute('field');
      this.form[field] = ''
    },

    /**
     * 图片组预览
     */
    pictureGroupPreview(file) {
      this.picturePreviewDialogVisible = true;
      this.picturePreviewIndex = this.picturePreviewList.findIndex(s=>s == `${file.response.data.path}/${file.response.data.storageName}`)
      // this.$refs.pictureGroupCarousel[0].setActiveItem(this.picturePreviewIndex)
    },
    /**
     * 图片组删除
     */
    pictureGroupRemove(file, fileList) {
      var field = this.$refs.$pictureGroupUpload[0].$el.getAttribute('field');
      this.form[field] = fileList.map((s) => $y._.assign(s,s.response ? s.response.data : {}));
      this.picturePreviewList = fileList.map((s) => $y._.assign(s,s.response ? s.response.data : {}));
      this.$emit("change", { field, event:this.form[field] });
    },
    /**
     * 图片组上传成功
     */
    pictureGroupSuccess(response, file, fileList,field) {
      var field = this.$refs.$pictureGroupUpload[0].$el.getAttribute('field');
      this.form[field] = fileList.map((s) => $y._.assign(s,s.response ? s.response.data : {}));
      this.picturePreviewList = fileList.map((s) => $y._.assign(s,s.response ? s.response.data : {}));
      this.$emit("change", { field, event:this.form[field] });

    },
    /**
     * 图片组错误
     */
    pictureGroupError(err, file, fileList) {
      var field = this.$refs.$pictureGroupUpload[0].$el.getAttribute('field');
      this.form[field] = fileList.map((s) => $y._.assign(s,s.response ? s.response.data : {}));
      this.picturePreviewList = fileList.map((s) => $y._.assign(s,s.response ? s.response.data : {}));
    },
    /**
     * 图片组进度
     */
    pictureGroupProgress(event, file, fileList) {},
    /**
     * 图片组修改
     */
    pictureGroupChange(file, fileList) {
      // this.picturePreviewList = fileList.map(
      //   (s) => `${s.response.data.path}/${s.response.data.storageName}`
      // );
    },
  },
};
</script>

<style lang="scss" scoped>
.form-module {
  .form-module-title {
    height: 40px;
    line-height: 40px;
    font-weight: bold;
  }
  .form-module-content {
  }
}
.el-input .el-input--small {
  width: 100%;
}

.avatar-uploader .el-upload:hover {
  border-color: #409EFF;
}
</style>